package com.xpu.demo;

import java.util.Stack;

/**
 * 设计一个特殊的栈，在实现栈基本功能上，在实现一个返回栈中最小元素的操作
 * 栈特性：先进后出
 * 解答：在设计师我们使用两个栈，一个用来包村当前栈中元素，其功能和普通栈没有区别，记为StackData；
 * 一个用于保存每一步的最小值，记为StackMin。
 */
public class MyStack {
   private Stack<Integer> stackData;
   private Stack<Integer> stackMin;

    public MyStack(Stack<Integer> stackData, Stack<Integer> stackMin) {
        this.stackData = stackData;
        this.stackMin = stackMin;
    }
    /**
     * 第一种设计方案：
     * 压入数据规则：
     * 假设当前数据为newNum，先将其压入stackData。然后判断stackMin是否为空
     * 如果为空则newNum也压入stackMin
     * 如果不为空，则比较newNum和stackMin的栈顶元素大小
     * 如果更小或相等，则newNum也压入stackMin
     * 如果stackMin栈顶元素小则ewNum不压入stackMin
     * 弹出数据规则：
     * 先在stackData中弹出栈顶元素，记为value。然后比较当前stackMin的栈顶元素和value哪一个更小。
     * 通过压入规则可知，stackMin元素从栈底到栈顶是逐渐变小的，即栈顶元素就是stackMin最小值，也是当前stackData最小值
     * 所以当value等于stackMin栈顶元素，即同时也弹出stackMin栈顶元素
     */
    public void push(int newNum){
        if(stackMin.isEmpty()){
            stackMin.push(newNum);
        }else if(newNum<=getMin()){
            stackMin.push(newNum);
        }
        stackData.push(newNum);
    }
    public int pop(){
        if(stackData.isEmpty()){
            throw new RuntimeException("Your stack is empty.");
        }
        int value=stackData.pop();
        if(value==getMin()){
            stackMin.pop();
        }
        return value;
    }
    public int getMin(){
        if(stackMin.isEmpty()){
            throw new RuntimeException("Your stack is empty");
        }
        return stackMin.peek();
    }


}
